<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
    <!--
        vue采用面向对象的方式对网页开发进行抽象。无论是单一网页还是整个网站，都视为一个应用程序。
        在vue应用程序中可以定义和使用多个组件，这些组件共同构成了用户界面。
        注意：我们需要一个根组件，它作为整个应用程序的入口点，当应用程序挂载并渲染到页面上时，根组件会作为渲染过程的起点元素。
    -->
    <div id="app">
        这里是根组件
        <h2>点击次数：{{countString}}</h2>
        <button @click="click">点击</button>
    </div>

<script>
    const {createApp,ref,computed,watch} = Vue
    const config = {
        /*
            在应用配置对象中，使用setup()方法进行组件的初始化
         */
        setup() {
            const data = ref({
                count: 0
            })
            // defineProps可以接收从父组件传递的数据。
            // defineProps(['param'])

            // computed() 可以用来配置计算属性，在其中可实现get(),set()方法
            const countString = computed({
                get() {
                    return data.value.count + '次'
                }
            })

            // 组件中可以定义方法
            // 注意：在方法当中不要使用this，因为在setup()函数被调用时，组件实例并未创建好，不可以使用this
            const click = () => {
                data.value.count++
            }

            // watch函数是用来对组件属性的变化添加监听
            // 这里我们监听的是data，它是一个对象，默认情况下我们只是对data的变化进行监听，其内部count属性的变化并不会监听
            // 如果我们需要监听data的count属性，那么我们可以设置监听器为深度监听模式：{deep:true}
            // 当开启深度监听后，参数newValue和oldValue的值都是相同的，都是data对象本身
            // 深度监听需要遍历被监听对象的所有嵌套属性，因此性能会消耗比较大，实际应用中要谨慎使用
            // 配置参数中还有once配置，当设置为true时表示只监听一次属性变化，后续的属性变化将不再监听
            watch(data, (newValue, oldValue) => {
                console.log(newValue, oldValue)
            },{deep:true,once:true})

            return {data,countString,click}
        }
    }

    /*
        createApp()方法用来返回一个Vue应用实例
        在创建应用实例时，可以传入一个JavaScript对象来提供创建应用时相关的配置项（组件的属性和方法的配置等）
    */
    const app = createApp(config)
    // 创建应用后可以使用mount方法把它绑定到指定的html元素中
    app.mount('#app')
</script>
</body>
</html>